//package com.anivia.common.web.config.columnPermission;
//
//import cn.hutool.core.collection.CollUtil;
//import cn.hutool.core.text.CharSequenceUtil;
//import cn.hutool.extra.spring.SpringUtil;
//import com.anivia.common.web.privoder.DataHandlerProvider;
//import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
//import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
//import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
//import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
//import lombok.extern.slf4j.Slf4j;
//import net.sf.jsqlparser.expression.Expression;
//import net.sf.jsqlparser.expression.Function;
//import net.sf.jsqlparser.parser.CCJSqlParserUtil;
//import net.sf.jsqlparser.schema.Column;
//import net.sf.jsqlparser.schema.Table;
//import net.sf.jsqlparser.statement.Statement;
//import net.sf.jsqlparser.statement.select.*;
//import net.sf.jsqlparser.util.TablesNamesFinder;
//import org.apache.ibatis.executor.Executor;
//import org.apache.ibatis.mapping.BoundSql;
//import org.apache.ibatis.mapping.MappedStatement;
//import org.apache.ibatis.session.ResultHandler;
//import org.apache.ibatis.session.RowBounds;
//import org.springframework.beans.factory.NoSuchBeanDefinitionException;
//
//import java.sql.SQLException;
//import java.util.*;
//
///**
// * 字段权限拦截器
// *
// * @author hj
// * @date 2024-03-29
// */
//@Slf4j
//public class ColumnDataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor {
//    @Override
//    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
//        if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {
//            return;
//        }
//        PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
//        mpBs.sql(this.parserSingle(mpBs.sql(), ms.getId()));
//    }
//
//    @Override
//    protected void processSelect(Select select, int index, String sql, Object obj) {
//        SelectBody selectBody = select.getSelectBody();
//        if (selectBody instanceof PlainSelect) {
//            PlainSelect plainSelect = (PlainSelect) selectBody;
//            Map<String, Object> columnMap = extractFields(plainSelect);
//            //字段列表
//            List<SelectItem> selectItems = plainSelect.getSelectItems();
//            //解析所有表
//            Map<String, String> tableMap = parseSqlToTable(sql);
//            //查询权限
//            Set<String> tabls = tableMap.keySet();
//            DataHandlerProvider provider = null;
//            try {
//                provider = SpringUtil.getBean(DataHandlerProvider.class);
//            } catch (NoSuchBeanDefinitionException e) {
//                throw new RuntimeException("当前服务未实现DataHandlerProvider，使用配置的数据脱敏权限功能无法使用。");
//            }
////            Map<String, Set<String>> permissionColum = provider.getPermissionColum(tabls);
//            //测试权限
//            Map<String, Set<String>> permissionColum = testPerssion();
//            if (permissionColum == null || CollUtil.isEmpty(permissionColum.keySet())) {
//                return;
//            }
//            //替换查询字段
//            List<SelectItem> replaceColum = parseAllPermissionColumToSet(permissionColum, tableMap, selectItems, columnMap);
//            plainSelect.setSelectItems(replaceColum);
//        }
//    }
//
//    private Map<String, Set<String>> testPerssion() {
//        Map<String, Set<String>> result = new HashMap<>();
//        Set<String> o1 = new HashSet<>();
//        o1.add("id");
//        o1.add("name");
//        o1.add("age");
//        o1.add("city");
//        result.put("admin_info", o1);
//
//        Set<String> o2 = new HashSet<>();
//        o2.add("id");
//        o2.add("name");
//        o2.add("age");
//        result.put("resource_info", o2);
//        return result;
//    }
//
//    private List<SelectItem> parseAllPermissionColumToSet(Map<String, Set<String>> permissionColum,
//                                                          Map<String, String> tableMap,
//                                                          List<SelectItem> selectItems, Map<String, Object> columnMap) {
//        //反转key
//        Map<String, String> valueAsKey = reversalMap(tableMap);
//        List<SelectItem> result = new ArrayList<>();
//        for (SelectItem selectItem : selectItems) {
//            if (selectItem instanceof AllTableColumns) {
//                AllTableColumns t = (AllTableColumns) selectItem;
//                //tableName可能是别名
//                String tableName = t.getTable().toString();
//                if (!CharSequenceUtil.isBlank(valueAsKey.get(tableName))) {
//                    tableName = valueAsKey.get(tableName);
//                }
//                Set<String> colums = permissionColum.get(tableName);
//                String tableAlias = tableMap.get(tableName);
//                result.addAll(packageAllItem(colums, tableAlias));
//            } else if (selectItem instanceof SelectExpressionItem) {
//                SelectExpressionItem t = (SelectExpressionItem) selectItem;
//                Object o = columnMap.get(t.getExpression().toString());
//                if (o instanceof String) {
//                    singleColumnpermission(permissionColum, tableMap, selectItem, t, valueAsKey, result);
//                } else if (o instanceof Set) {
//                    Set<String> columnSet = (Set<String>) o;
//                    boolean finalPermission = true;
//                    for (String column : columnSet) {
//                        String[] tablesSplit = column.split("\\.");
//                        String columName = tablesSplit.length > 1 ? tablesSplit[1] : tablesSplit[0];
//                        String tableName;
//                        if (tablesSplit.length > 1) {
//                            tableName = tablesSplit[0];
//                        } else {
//                            assert tableMap.keySet().size() == 1;
//                            tableName = tableMap.keySet().iterator().next();
//                        }
//                        if (!CharSequenceUtil.isBlank(valueAsKey.get(tableName))) {
//                            tableName = valueAsKey.get(tableName);
//                        }
//                        finalPermission &= columHasPermission(tableName, columName, permissionColum);
//                    }
//                    if (finalPermission) {
//                        result.add(selectItem);
//                    }
//                }
//            }
//        }
//        return result;
//    }
//
//    private void singleColumnpermission(Map<String, Set<String>> permissionColum, Map<String, String> tableMap, SelectItem selectItem, SelectExpressionItem t, Map<String, String> valueAsKey, List<SelectItem> result) {
//        String[] tablesSplit = t.getExpression().toString().split("\\.");
//        String columName = tablesSplit.length > 1 ? tablesSplit[1] : tablesSplit[0];
//        String tableName;
//        if (tablesSplit.length > 1) {
//            tableName = tablesSplit[0];
//        } else {
//            assert tableMap.keySet().size() == 1;
//            tableName = tableMap.keySet().iterator().next();
//        }
//        if (!CharSequenceUtil.isBlank(valueAsKey.get(tableName))) {
//            tableName = valueAsKey.get(tableName);
//        }
//        boolean hasPermission = columHasPermission(tableName, columName, permissionColum);
//        if (hasPermission) {
//            result.add(selectItem);
//        }
//    }
//
//    private boolean columHasPermission(String tableName, String columName, Map<String, Set<String>> permissionColum) {
//        Set<String> colums = permissionColum.get(tableName);
//        return colums != null && colums.contains(columName);
//    }
//
//
//    private Map<String, String> reversalMap(Map<String, String> tableMap) {
//        Map<String, String> invertedMap = new HashMap<>();
//        for (Map.Entry<String, String> entry : tableMap.entrySet()) {
//            if (entry.getValue() != null) {
//                invertedMap.put(entry.getValue(), entry.getKey());
//            }
//        }
//        return invertedMap;
//    }
//
//    private List<SelectItem> packageAllItem(Set<String> colums, String tableAlias) {
//        List<SelectItem> result = new ArrayList<>();
//        for (String colum : colums) {
//            SelectExpressionItem selectExpressionItem = new SelectExpressionItem();
//            Expression sqlColumn = new Column(CharSequenceUtil.isNotBlank(tableAlias) ? tableAlias + "." + colum : colum);
//            selectExpressionItem.setExpression(sqlColumn);
//            result.add(selectExpressionItem);
//
//        }
//        return result;
//    }
//
//    /**
//     * 解析sql中所有的表
//     *
//     * @param sql
//     * @return {@link List}<{@link String}>
//     */
//    private Map<String, String> parseSqlToTable(String sql) {
//        try {
//            Statement statement = CCJSqlParserUtil.parse(sql);
//            return getTableAliasMap(statement);
//        } catch (Exception e) {
//            throw new RuntimeException("解析sql失败");
//        }
//    }
//
//    public static Map<String, String> getTableAliasMap(Statement statement) {
//        Map<String, String> tableAliasMap = new HashMap<>();
//        statement.accept(new TablesNamesFinder() {
//            @Override
//            public void visit(Table table) {
//                String tableName = table.getName();
//                String alias = table.getAlias() != null ? table.getAlias().getName() : null;
//                tableAliasMap.put(tableName, alias);
//            }
//        });
//        return tableAliasMap;
//    }
//
//
//    public static Map<String, Object> extractFields(PlainSelect plainSelect) {
//        final Map<String, Object> fields = new HashMap<>();
//        for (SelectItem item : plainSelect.getSelectItems()) {
//            item.accept(new SelectItemVisitorAdapter() {
//                @Override
//                public void visit(SelectExpressionItem selectExpressionItem) {
//                    Expression expression = selectExpressionItem.getExpression();
//                    if (expression instanceof Function) {
//                        Function function = (Function) expression;
//                        String key = function.toString();
//                        // 处理函数内的字段
//                        List<Expression> expressions = function.getParameters().getExpressions();
//                        Set<String> columnSet = new HashSet<>();
//                        for (Expression expr : expressions) {
//                            if (expr instanceof Column) {
//                                Column column = (Column) expr;
//                                columnSet.add(column.getFullyQualifiedName());
//                            }
//                        }
//                        fields.put(key, columnSet);
//                    } else if (expression instanceof Column) {
//                        Column column = (Column) expression;
////                        fields.add(column.getFullyQualifiedName());
//                        fields.put(column.toString(), column.toString());
//                    }
//                }
//            });
//            if (item instanceof AllTableColumns) {
//                fields.put(item.toString(), item.toString());
//            }
//        }
//        return fields;
//    }
//}
